home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 2000
/
MacHack 2000.toast
/
pc
/
Presentations
/
Closures, Observers, Properties
/
COP Slides
< prev
Wrap
Text File
|
2000-06-22
|
7KB
|
561 lines
User interface ---------> Model
AppleScript ---------------> |-----------|
| |
User interface ------------> | Model |
| |
Network interface ---------> |-----------|
Button -------------> Action
Button -------------> Action
void (*action)()
struct Closure
{
Model *model;
Closure( Model& theModel )
: model( &theModel )
{}
void operator()() const
{
model->Method();
}
};
struct Closure
{
Model *model;
void (Model::*method)();
Closure( Model& theModel, void (Model::*theMethod)() )
: model( &theModel ),
method( theMethod )
{}
void operator()() const
{
(model->*method)();
}
};
struct Closure
{
void *genericModel;
void (Model::*method)();
Closure( Model& theModel, void (Model::*theMethod)() )
: genericModel( &theModel ),
method( theMethod )
{}
void operator()() const
{
Model& model = *static_cast<Model*>( genericModel );
( model->*method )();
}
};
struct Closure
{
class Generic;
void *genericModel;
void (Generic::*genericMethod)();
Closure( Model& theModel, void (Model::*theMethod)() )
: genericModel( &theModel ),
genericMethod( reinterpret_cast< void (Generic::*)() >( theMethod ) )
{}
void operator()() const
{
Model& model = *static_cast<Model*>( genericModel );
void (Model::*method)() =
reinterpret_cast< void (Model::*)() >( genericMethod );
( model->*method )();
}
};
struct Closure
{
class Generic;
void *genericModel;
void (Generic::*genericMethod)();
template < class Model >
Closure( Model& theModel, void (Model::*theMethod)() )
: genericModel( &theModel ),
genericMethod( reinterpret_cast< void (Generic::*)() >( theMethod ) )
{}
template < class Model >
void operator()() const
{
Model& model = *static_cast<Model*>( genericModel );
void (Model::*method)() =
reinterpret_cast< void (Model::*)() >( genericMethod );
( model->*method )();
}
};
struct Closure
{
class Generic;
void *genericModel;
void (Generic::*genericMethod)();
void (*thunk)( const Closure& );
template < class Model >
Closure( Model& theModel, void (Model::*theMethod)() )
: genericModel( &theModel ),
genericMethod( reinterpret_cast< void (Generic::*)() >( theMethod ) ),
thunk( Thunk<Model> )
{}
template < class Model >
void Thunk( const Closure& self ) const
{
Model& model = *static_cast<Model*>( self.genericModel );
void (Model::*method)() =
reinterpret_cast< void (Model::*)() >( self.genericMethod );
( model->*method )();
}
void operator()() const { (*thunk)( *this ); }
};
template < class Signature >
class Closure;
// Specialization for no parameters
template < class Result >
class Closure< Result (*)() >;
// Specialization for one parameter
template < class Result, class P >
class Closure< Result (*)(P) >;
// Specialization for two parameters
template < class Result, class P0, class P1 >
class Closure< Result (*)(P0,P1) >;
// And so on...
template < class Result > // Specialization for no parameters
struct Closure< Result (*)() >
{
class Generic;
void *genericModel;
void (Generic::*genericMethod)();
Result (*thunk)( const Closure& );
template < class Model >
Closure( Model& theModel, Result (Model::*theMethod)() )
: genericModel( &theModel ),
genericMethod( reinterpret_cast< void (Generic::*)() >( theMethod ) ),
thunk( Thunk<Model> )
{}
template < class Model >
Result Thunk( const Closure& self ) const
{
Model& model = *static_cast<Model*>( self.genericModel );
Result (Model::*method)() =
reinterpret_cast< Result (Model::*)() >( self.genericMethod );
return ( model->*method )();
}
Result operator()() const { return (*thunk)( *this ); }
};
template < class Result, class P > // Specialization for one parameter
struct Closure< Result (*)(P) >
{
class Generic;
void *genericModel;
void (Generic::*genericMethod)();
Result (*thunk)( const Closure&, P );
template < class Model >
Closure( Model& theModel, Result (Model::*theMethod)(P) )
: genericModel( &theModel ),
genericMethod( reinterpret_cast< void (Generic::*)() >( theMethod ) ),
thunk( Thunk<Model> )
{}
template < class Model >
Result Thunk( const Closure& self, P parameter ) const
{
Model& model = *static_cast<Model*>( self.genericModel );
Result (Model::*method)(P) =
reinterpret_cast< Result (Model::*)(P) >( self.genericMethod );
return ( model->*method )( parameter );
}
Result operator()( P parameter ) const { return (*thunk)( *this, parameter ); }
};
Standard File Dialog -------------> Volume List
template < class Signature > class Observable;
template < class Signature > class Observation;
template < class P >
struct Observable< void(*)(P) > // Specialization for one parameter
{
typedef Closure< void(*)(P) > Observer;
typedef LinkedList< Observer > List;
mutable List observers;
void Broadcast( P parameter ) const
{
for ( List::const_iterator observer = observers.begin();
observer != observers.end();
++observer )
(*observer)( parameter );
}
};
template < class Signature > class Observable;
template < class Signature > class Observation;
template < class Signature >
struct Observation
{
typedef Observable< Signature >::Observer Observer;
typedef Observable< Signature >::List List;
List::Link link;
Observation( const Observable<Signature>& observed,
Observer observer )
: link( observer )
{
observed.observers.push_back( link );
}
};
Boolean AppleScript Property -------------> Zoomed
template < class Type >
struct Property
{
Closure< Type (*)() > get;
Closure< void (*)( Type ) > set;
operator Type() const
{
return get();
}
Property& operator=( Type value )
{
set( value );
return *this;
}
Property& operator=( const Property& value )
{
set( value.get() );
return *this;
}
};
Checkbox -------------> Boolean property
template < class Type >
struct ObservableProperty: public Observable< void (*)(Type) >
{
Closure< Type (*)() > get;
Closure< void (*)( Type ) > set;
operator Type() const
{
return get();
}
Property& operator=( Type value )
{
set( value );
Broadcast( get() );
return *this;
}
Property& operator=( const Property& value )
{
set( value.get() );
Broadcast( get() );
return *this;
}
};